﻿using System;
using System.Timers;

namespace maranov.TeaTimer
{
    /// <summary>
    /// Časovač pro měření času přípravy nápojů a zobrazení průběhu.
    /// </summary>
    public class TeaTimer : ITeaTimer
    {
        /// <summary>
        /// Výchozí hodnota intervalu tiku časovače.
        /// </summary>
        private const double DefaultTickInterval = 200;

        /// <summary>
        /// Interní časovač pro vypršení času.
        /// </summary>
        private Timer SoakTimer;

        /// <summary>
        /// Interní časovač pro tiky.
        /// </summary>
        private Timer TickTimer;

        /// <summary>
        /// Generátor náhodných časů dle rozsahu.
        /// </summary>
        private Random TimeGenerator;

        /// <summary>
        /// Čas dokončení.
        /// </summary>
        private DateTime TimeFinished;

        /// <summary>
        /// Časovač pro měření času přípravy nápojů a zobrazení průběhu.
        /// </summary>
        /// <param name="tickInterval">Interval tiku měřeného času.</param>
        public TeaTimer(double tickInterval = DefaultTickInterval)
        {
            SoakTimer = new Timer();
            SoakTimer.AutoReset = false;
            SoakTimer.Elapsed += new ElapsedEventHandler(
                delegate(Object sender, ElapsedEventArgs e)
                {
                    if (TimeUp != null)
                    {
                        TimeUp(this, EventArgs.Empty);
                    }
                });

            TickTimer = new Timer(tickInterval);
            TickTimer.AutoReset = true;
            TickTimer.Elapsed += new ElapsedEventHandler(
                delegate(Object sender, ElapsedEventArgs e)
                {
                    if (Tick != null)
                    {
                        Tick(this, new TickEventArgs(TimeFinished - DateTime.Now, Overtime));
                    }
                });

            TimeGenerator = new Random();
        }

        public int Start(int minutesMin, int minutesMax)
        {
            int seconds = TimeGenerator.Next(minutesMin * 60, minutesMax * 60);
            SoakTimer.Interval = seconds * 1000;
            SoakTimer.Start();
            TickTimer.Start();
            TimeFinished = DateTime.Now + new TimeSpan(0, 0, seconds);
            return seconds;
        }

        public bool Stop()
        {
            bool elapsed = Overtime;
            SoakTimer.Stop();
            TickTimer.Stop();
            return elapsed;
        }

        public event EventHandler<EventArgs> TimeUp;

        public event EventHandler<TickEventArgs> Tick;

        public double TickInterval
        {
            get
            {
                return TickTimer.Interval;
            }
            set
            {
                TickTimer.Interval = value;
            }
        }

        public bool Running
        {
            get { return TickTimer.Enabled; }
        }

        public bool Overtime
        {
            get { return !SoakTimer.Enabled && Running; }
        }
    }
}
